package com.yonyougov.devops.cruxcisupport.appenvport;

import com.yonyougov.devops.cruxcisupport.appenv.dto.port.*;
import com.yonyougov.devops.cruxcisupport.appenv.vo.AppEnvPortVo;
import com.yonyougov.devops.cruxcisupport.appenv.vo.port.instance.EnvAppServerInfoVo;
import com.yonyougov.devops.cruxcisupport.env.EnvEntity;
import com.yonyougov.devops.cruxcisupport.env.EnvService;
import com.yonyougov.devops.fwc.api.dto.BaseResponseDto;
import com.yonyougov.devops.fwc.core.controller.CrudController;
import com.yonyougov.devops.fwc.core.entity.Pagination;
import com.yonyougov.devops.fwc.core.service.BaseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ligson on 2017/8/11.
 */
@Api(tags = "端口映射模块")
@RestController
@RequestMapping("/api/v2/appenvport")
public class AppEnvPortController extends CrudController<AppEnvPortEntity, BigInteger> {

    @Value("${env.names:}")
    private String evnNames;

    private final AppEnvPortService appEnvPortService;
    private final EnvService envService;

    public AppEnvPortController(AppEnvPortService appEnvPortService, EnvService envService) {
        this.appEnvPortService = appEnvPortService;
        this.envService = envService;
    }

    @Override
    public BaseService<AppEnvPortEntity, BigInteger> getService() {
        return appEnvPortService;
    }


    //<!--用户自定义代码开始-->

    @PostMapping(value = "/aep/add")
    public BaseResponseDto addAppEnvPort(@RequestBody @Valid AppEnvPortAddRequestDto requestDto) {
        AppEnvPortEntity appEnvPortEntity = new AppEnvPortEntity();
        BeanUtils.copyProperties(requestDto, appEnvPortEntity);
        appEnvPortService.add(appEnvPortEntity);
        return BaseResponseDto.getSuccessInstance();
    }
    //<!--用户自定义代码结束-->

    @PostMapping(value = "/aep/update")
    public BaseResponseDto updateAppEnvPort(@RequestBody @Valid AppEnvPortUpdateRequestDto requestDto) {
        AppEnvPortEntity appEnvPortEntity = new AppEnvPortEntity();
        BeanUtils.copyProperties(requestDto, appEnvPortEntity);
        if(null == appEnvPortEntity.getMappingPort()){
            appEnvPortEntity.setMappingPort(-1);
        }
        appEnvPortService.update(appEnvPortEntity);
        return BaseResponseDto.getSuccessInstance();
    }

    @PostMapping(value = "/aep/page")
    public AppEnvPortQueryResponseDto findAppEnvPortPage(@RequestBody AppEnvPortQueryRequestDto requestDto) {
        AppEnvPortEntity appEnvPortEntity = new AppEnvPortEntity();
        BeanUtils.copyProperties(requestDto, appEnvPortEntity);
        Pagination<AppEnvPortEntity> pagination = appEnvPortService.findAllBy(appEnvPortEntity);
        List<AppEnvPortVo> appEnvPortVoList = new ArrayList<>();
        pagination.getDatas().forEach(entity -> {
            AppEnvPortVo appEnvPortVo = new AppEnvPortVo();
            BeanUtils.copyProperties(entity, appEnvPortVo);
            appEnvPortVoList.add(appEnvPortVo);
        });
        return new AppEnvPortQueryResponseDto(pagination.getTotalCount(), pagination.getPageCount(),
                pagination.getPageSize(), pagination.getPageNum(), appEnvPortVoList);
    }

    @PostMapping(value = "/aep/delete/id")
    public BaseResponseDto deleteAppEnvPortById(@RequestBody @Valid AppEnvPortDeleteRequestDto requestDto) {
        appEnvPortService.deleteByPrimaryKey(requestDto.getId());
        return BaseResponseDto.getSuccessInstance();
    }

    @ApiOperation(value = "", notes = "自动生成端口")
    @PostMapping(value = "/aep/generateMappingPort")
    public BaseResponseDto generateMappingPort(@RequestBody GenerateMappingPortRequestDto request) {
        BigInteger envId = request.getEnvId();
        appEnvPortService.generateMappingPort(envId);
        return BaseResponseDto.getSuccessInstance();
    }
    @ApiOperation(value = "", notes = "针对某个环境下的应用自动生成端口")
    @PostMapping(value = "/aep/generateAppMappingPort")
    public BaseResponseDto generateAppMappingPort(@RequestBody GenerateAppMappingPortRequestDto request) {
        BigInteger appEnvId = request.getAppEnvId();
        appEnvPortService.generateAppMappingPort(appEnvId);
        return BaseResponseDto.getSuccessInstance();
    }

    @ApiOperation(value = "获取某个环境某个应用对外的映射端口", notes = "获取映射端口")
    @PostMapping(value = "/aep/mappingPort")
    public List<Integer> getMappingPort(@RequestBody @Valid MappingPortRequestDto request) {
        String envName = request.getEnvName();
        String appName = request.getAppName();
        return appEnvPortService.getMappingPort(envName, appName);
    }

    @ApiOperation(value = "获取环境应用服务信息", notes = "获取环境应用服务信息")
    @PostMapping(value = "/aep/serverInfo")
    public Map<String, Object> getEnvAppServerInfo(@RequestBody @Valid EnvAppServerInfoRequestDto request) {
        String envName = request.getEnvName();
        String appName = request.getAppName();

        EnvAppServerInfoVo appServerInfoVo = appEnvPortService.getEnvAppServerInfo(envName, appName);
        Map<String, Object> appServerInfoMap = new HashMap<>();
        /***
         * private InstanceVo instance;
         *     private EnvClusterVo cluster;
         *     private String masterIp;
         *     private boolean exposePort;
         */
        Map<String, Object> instanceMap = new HashMap<>();
        if (StringUtils.isNotBlank(evnNames)) {
            String[] envNames = evnNames.split(",");
            if (ArrayUtils.contains(envNames, envName)) {
                appServerInfoMap.put("masterIp", appServerInfoVo.getMasterIp());
                appServerInfoMap.put("exposePort", appServerInfoVo.isExposePort());
            }
            if (ArrayUtils.contains(envNames, envName)) {
                instanceMap.put("exposePort", appServerInfoVo.getInstance().isExposePort());
            }
        }
        instanceMap.put("ports", appServerInfoVo.getInstance().getPorts());

        Map<String, Object> clusterMap = new HashMap<>();
        clusterMap.put("nodes", appServerInfoVo.getCluster().getNodes());

        appServerInfoMap.put("instance", instanceMap);
        appServerInfoMap.put("cluster", clusterMap);

        return appServerInfoMap;
    }
}
